package com.wss.lsl.alading.service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.wss.lsl.alading.domain.Member;
import com.wss.lsl.alading.domain.Merchandise;
import com.wss.lsl.alading.domain.OrderForm;
import com.wss.lsl.alading.domain.YGDDMX;
import com.wss.lsl.alading.domain.YGDDZB;
import com.wss.lsl.alading.mapper.ExchangeLogMapper;
import com.wss.lsl.alading.mapper.MemberMapper;
import com.wss.lsl.alading.mapper.OrderFormMapper;
import org.springframework.transaction.annotation.Propagation;

@Service
public class CouponService implements ICouponService {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private OrderFormMapper orderFormMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private ExchangeLogMapper exchangeLogMapper;

    @Transactional
    @Override
    public String exchange(String couponNo, int accountId, int quantity,
            String terminalId, String terminalAddress, String transactionDate) {

        String errorMessage = "";
        String returnCode = "";
        Member member = null;

        try {
            // 114 日期格式检查
            SimpleDateFormat dateFormat = new SimpleDateFormat(
                    "yyyy-MM-dd HH:mm:ss");
            dateFormat.parse(transactionDate);

            try {
                if (couponNo == null || "".equals(couponNo)) { // validate couponNO 
                    errorMessage = "CouponNo could not allow empty!";
                    returnCode = "113";
                } else if (orderFormMapper.checkCouponNo(couponNo) >= 1) {// check coupon whether exists
                    errorMessage = "CouponNo already exists!";
                    returnCode = "101";
                } else {
                    member = orderFormMapper.selectMemberById(accountId);
                    if (null == member) { // find employee, employee not exists or member is locked
                        errorMessage = "No or mutilpart employee is found!";
                        returnCode = "113";
                    } else if (member.getBalance() == null) {
                        errorMessage = "Employee jf is NULL";
                        returnCode = "113";
                    } else {
                        Merchandise merchandise = orderFormMapper.selectMerchandiseBySPBH();
                        if (null == merchandise) {
                            errorMessage = "Coupon merchandise is not found!";
                            returnCode = "113";
                        } else {
                            BigDecimal sumAmount = merchandise.getUnitprice().multiply(new BigDecimal(quantity));
                            if (sumAmount.compareTo(new BigDecimal(0)) <= 0) {
                                errorMessage = "Payment could not less zero!";
                                returnCode = "113";
                            } else if (sumAmount.compareTo(member.getBalance()) > 0) { // check employee balance whether enough to pay
                                errorMessage = "employee balance is not enough to pay!";
                                returnCode = "102";
                            } else {
                                YGDDZB ygddzb = new YGDDZB(couponNo, sumAmount, accountId);
                                orderFormMapper.insertYGDDZB(ygddzb);
                                orderFormMapper.insertYGDDMX(new YGDDMX(ygddzb.getId(), merchandise.getId(), quantity, sumAmount, accountId, merchandise.getSplId(), couponNo));
                                orderFormMapper.updateMemberBalance(accountId, sumAmount);
                                sumAmount.intValue();
                                orderFormMapper.insertOrderForm(couponNo, merchandise.getMarketprice(), quantity, merchandise.getId(), transactionDate, accountId, member.getMobilePhone(), sumAmount, member.getEnterpriseId());
                                returnCode = "100";
                            }
                        }
                    }
                }
            } catch (Exception e) {
                errorMessage = "Unknow error!";
                returnCode = "113";
            }

        } catch (Exception e) {
            errorMessage = "date format error!";
            returnCode = "114";
        }

        // insert log
        orderFormMapper.insertExchangelog(terminalId, "ishelf", terminalAddress, couponNo, "exchange", returnCode, errorMessage, transactionDate, member == null ? "" : member.getMobilePhone(), "");
        return returnCode;
    }

    @Transactional
    @Override
    public String applyCoupon(List<String> couponNo, String terminalId,
            String merchantName, String merchantAddress,
            String transactionDate, String transactionNo) {

        // 114 日期格式检查
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(
                    "yyyy-MM-dd HH:mm:ss");
            dateFormat.parse(transactionDate);
        } catch (Exception e) {
            return "114";
        }

        boolean isEmpty = true;
        String returnCode = "";
        for (String cp : couponNo) {
            if (StringUtils.isNotEmpty(cp)) {
                isEmpty = false;
            } else {
                isEmpty = true;
                break;
            }
        }
        if (isEmpty) {
            logger.warn("Call applyCoupon that CouponNo is empty!");
            throw new IllegalStateException(returnCode);
        }

        for (String cp : couponNo) {
            returnCode = applyCoupon(cp, terminalId, merchantName,
                    merchantAddress, transactionDate, transactionNo);

            // One of coupon failed rollback all
            if (returnCode == null || !returnCode.equals("100")) {
                throw new IllegalStateException(returnCode);
            }
        }

        return returnCode;
    }

    private String applyCoupon(String couponNo, String terminalId,
            String merchantName, String merchantAddress,
            String transactionDate, String transactionNo) {

        String errorMessage = "";
        String returnCode = "";
        Member member = null;

        try {
            // 114 日期格式检查
            SimpleDateFormat dateFormat = new SimpleDateFormat(
                    "yyyy-MM-dd HH:mm:ss");
            dateFormat.parse(transactionDate);

            try {
                if (orderFormMapper.checkCouponNo(couponNo) < 1) {// check coupon whether exists
                    errorMessage = "CouponNo not exists!";
                    returnCode = "101";
                } else {
                    OrderForm orderForm = orderFormMapper.selectByCouponNo(couponNo);
                    member = orderFormMapper.selectMemberById(orderForm.employeeId);
                    if (null == member) { // member is locked
                        returnCode = "121";
                    } else if (orderForm.status == 0) {
                        orderFormMapper.changeOrderFormState(2, transactionNo, orderForm.id);
                        orderFormMapper.updateYGDDZB_state(5, couponNo);
                        orderFormMapper.updateYGDDMX_state(5, couponNo);
                        returnCode = "100";
                    } else if (orderForm.status == 1) {
                        // expired
                        returnCode = "102";
                    } else {
                        // other couponNo state
                        returnCode = "103";
                    }
                }
            } catch (Exception e) {
                errorMessage = "Unknow error!";
                returnCode = "113";
            }

        } catch (Exception e) {
            errorMessage = "date format error!";
            returnCode = "114";
        }

        // insert log
        orderFormMapper.insertExchangelog(terminalId, "ishelf", merchantAddress, couponNo, "apply", returnCode, errorMessage, transactionDate, member == null ? "" : member.getMobilePhone(), transactionNo);
        return returnCode;
    }

    @Transactional
    @Override
    public String expireCoupon(List<String> couponNo) {

        boolean isEmpty = true;
        String returnCode = "";
        
        // check paramter format
        for (String cn : couponNo) {
            if (StringUtils.isNotEmpty(cn)) {
                isEmpty = false;
            } else {
                isEmpty = true;
                break;
            }
        }
        if (isEmpty) {
            logger.warn("Call expireCoupon that CouponNo is empty!");
            throw new IllegalStateException(returnCode);
        }

        // handler business
        for (String cn : couponNo) {
            returnCode = expireCoupon(cn);
            
            

            // One of coupon failed rollback all
            if (!returnCode.equals("100")) {
                throw new IllegalStateException(returnCode);
            }
        }

        return returnCode;
    }
    
    @Transactional
    @Override
    public String expireCoupon(String couponNo) {

        String errorMessage = "";
        String returnCode = "";
        Member member = null;

        try {
            if (StringUtils.isEmpty(couponNo)) {
                errorMessage = "";
                returnCode = "113";
            } else {
                OrderForm orderForm = orderFormMapper
                        .selectByCouponNo(couponNo);
                if (null == orderForm) {
                    // couponNo is not exists
                    returnCode = "101";
                } else if (orderForm.status == 0) {
                    member = orderFormMapper.selectMemberById(orderForm.employeeId);
                    if (null == member) { // member is locked
                        returnCode = "121";
                    } else {
                        // usable
                        orderFormMapper.changeOrderFormState2(3, orderForm.id);
                        orderFormMapper.updateMemberBalance(orderForm.employeeId, new BigDecimal(0 - orderForm.units));
                        orderFormMapper.updateYGDDZB_state(9, couponNo);
                        orderFormMapper.updateYGDDMX_state(9, couponNo);
                        returnCode = "100";
                    }
                } else if (orderForm.status == 1) {
                    // expired
                    returnCode = "102";
                } else {
                    // other couponNo state
                    returnCode = "103";
                }
            }
        } catch (Exception e) {
            errorMessage = "Unknow error!";
            returnCode = "113";
        }
        
        // insert log
        orderFormMapper.insertExchangelog("", "ishelf", "", couponNo, "expire", returnCode, errorMessage, null, member == null ? "" : member.getMobilePhone(), "");
        return returnCode;
    }
}
